#include "DirectX.h"

// Constructor
CDirectX::CDirectX(void)
{

}

// Destructor
CDirectX::~CDirectX(void)
{

}

bool CDirectX::Init( HWND hWnd, HINSTANCE hInst, int nWidth, 
					int nHeight, bool bWindowed)
{
	// Start D3D, detect device type and capabilities, detect
	// video modes and formats, create the D3d device
	m_pD3DObject = Direct3DCreate9( D3D_SDK_VERSION);

	// D3DPRESENT_PARAMETERS define how the device will display
	// graphics to the screen
	D3DPRESENT_PARAMETERS	m_D3Dpp;
	ZeroMemory( &m_D3Dpp, sizeof( m_D3Dpp));	//clears the memory

	m_D3Dpp.Windowed = bWindowed;
	m_D3Dpp.hDeviceWindow = hWnd;
	m_D3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
	m_D3Dpp.BackBufferWidth = nWidth;
	m_D3Dpp.BackBufferHeight = nHeight;
	m_D3Dpp.BackBufferCount = 1;
	m_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	m_D3Dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

	// Enable the Z-Buffer for "depth" - so back objects do not
	// overwrite forward objects based on draw order
	m_D3Dpp.EnableAutoDepthStencil = TRUE;
	m_D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;

	/*
	Full scene anti-aliasing refers to blurring the edges of
	each polygon in the scene as it is rasterized in a single pass.
	Done in Direct3D by using multi-sampling, if hardware supported.
	Multi-sampling is turned on by your D3DPRESENT_PARAMETERS.
	Depending on the hardware, you can check from 0-16 before Device is created
	*/
	if( SUCCEEDED( m_pD3DObject->CheckDeviceMultiSampleType(
		D3DADAPTER_DEFAULT,		// Default adapter
		D3DDEVTYPE_HAL,			// Device type
		D3DFMT_X8R8G8B8, bWindowed,	// Surface, windowed/full screen
		D3DMULTISAMPLE_2_SAMPLES, NULL)))	// D3DMULTISAMPLE_TYPE
	{
		// This multi-sample pass succeeded so enable it
		m_D3Dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
	}

	// Create our D3D Device with our new parameters
	HRESULT result;
	result = m_pD3DObject->CreateDevice(
		D3DADAPTER_DEFAULT,	// primary display adapter
		D3DDEVTYPE_HAL,		// device type to use
		hWnd,				// focus window
		D3DCREATE_HARDWARE_VERTEXPROCESSING,	// behavior flag
		&m_D3Dpp,			// presentation parameters (pointer)
		&m_pD3DDevice);		// returned device pointer

	// Error check to see if the D3D Device succeeded or not
	if( FAILED( result))
		return false;

	// After D3D Device is created, turn on the Anti-Aliasing
	m_pD3DDevice->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, TRUE);

	// Turn on the Z-Buffer so back objects do not overwrite
	// the forward objects based on draw order
	m_pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE);

	// Create our Gameplay Object ("Main Class")
	m_pGameplay = new Gameplay();
	m_pGameplay->Init(m_pD3DDevice, hWnd, hInst, nWidth, nHeight);

	// Everything worked properly, so return true
	return true;
}

void CDirectX::Update(HWND hWnd, HINSTANCE hInst, int nWidth, int nHeight, float deltaTime)
{
	m_pGameplay->Update(hWnd, hInst, deltaTime);
}

bool CDirectX::Render(float deltaTime)
{
	// Error check
	if( !m_pD3DDevice)
		return false;

	// Clear the screen
	m_pD3DDevice->Clear(
		0,					// Number of rects
		NULL,				// Array of rects
		D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,	// Buffer to clear
		D3DCOLOR_XRGB(0, 0, 0),		// 32-bit color
		1.0f,				// Z-Buffer depth
		0);					// Stencil buffer value

	// Draw things here
	if(SUCCEEDED(m_pD3DDevice->BeginScene()))
	{
		m_pGameplay->Render(deltaTime);

		m_pD3DDevice->EndScene();
	}

	// Display the backbuffer
	m_pD3DDevice->Present(
		NULL,				// Source rectangle
		NULL,				// Destination rectangle
		NULL,				// Destination window
		NULL);				// Minimum set of pixels from source

	// Everything is good
	return true;
}
void CDirectX::Shutdown()
{
	// Destroy the gameplay class
	if(m_pGameplay)
	{
		m_pGameplay->Shutdown();
		delete m_pGameplay;
		m_pGameplay = NULL;
	}
	// Release D3D Device
	if( m_pD3DDevice)
	{
		m_pD3DDevice->Release();	// Device released first
		m_pD3DDevice = NULL;
	}

	// Release D3D Object
	if( m_pD3DObject )
	{
		m_pD3DObject->Release();	// D3D Object released last
		m_pD3DObject = NULL;
	}
}
